package com.ebupt.migu.music.schedule.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.ebupt.migu.music.common.entity.ResultObject;
import com.ebupt.migu.music.common.exception.MyException;
import com.ebupt.migu.music.common.exception.StatusEnum;
import com.ebupt.migu.music.common.util.DateUtil;
import com.ebupt.migu.music.redis.service.RedisService;
import com.ebupt.migu.music.schedule.Enum.UserGroupConstants;
import com.ebupt.migu.music.schedule.entity.ArkUserGroupInfo;
import com.ebupt.migu.music.schedule.mapper.UserGroupInfoMapper;
import com.ebupt.migu.music.schedule.service.MutualArkService;
import com.ebupt.migu.music.userGroup.entity.UserGroupInfo;
import com.ebupt.migu.music.userGroup.mapper.CrowdMapper;
import com.ebupt.migu.music.userGroup.service.FileUploadService;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.*;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class MutualArkServiceImpl implements MutualArkService {

    @Autowired
    private UserGroupInfoMapper userGroupInfoMapper;

    @Autowired
    private CrowdMapper crowdMapper;

    @Autowired
    private FileUploadService fileUploadService;

    @Autowired
    private RedisService redisService;

    // 文件默认保存路径
    @Value("${path.file_upload}")
    private String FILE_UPLOAD_PATH;

    @Override
    public boolean deleteUserGroup() {
        int result = userGroupInfoMapper.deleteByState(UserGroupConstants.USER_GROUP_IMPORTED_STATE);
        if (result<=0){
            return false;
        }
        return true;
    }

    @Override
    public void importUserGroupInfo() {
        try {
            //获取一共有多少客群
            List<String> groups = userGroupInfoMapper.getAllGroupId();
            log.info("本次更新共{}个客群",groups.size());
            if (groups.size()<=0){
                return;
            }
            for (String userName : groups) {
                if(StringUtils.isBlank(userName)){
                    continue;
                }
                //查询出客群中所有的号码数
                List<ArkUserGroupInfo> UserGroupInfoItem = userGroupInfoMapper.selectByUserName(userName);
                HashMap userGroupMap = crowdMapper.isUserGroupNameExist(userName);
                if (userGroupMap == null){
                    //新增客群
                    if (!insertGroupInfo(UserGroupInfoItem,userName)){
                        log.error("新增客群{}异常",userName);
                        continue;
                    }
                }else {
                    //更新客群
                    if (!updateGroupInfo(UserGroupInfoItem,userGroupMap)){
                        continue;
                    }
                }
                userGroupInfoMapper.updateAllState(UserGroupConstants.USER_GROUP_IMPORTED_STATE,userName);
            }
        }catch (Exception e){
            throw e;
        }
    }

    private boolean insertGroupInfo(List<ArkUserGroupInfo> userGroupInfoItem, String userName) {
        String fileName = DateUtil.parseDateToStr(new Date(), DateUtil.DATE_TIME_FORMAT_YYYYMMDDHHMISS) + ".csv";//CSV文件名称
        //拼接文件路径
        String url = FILE_UPLOAD_PATH + fileName;
        //建立一个csv文件,并存入ftp目录中
        PointsToCsvFile(userGroupInfoItem,url);
        //新建一个导入客群
        ResultObject resultObject = fileUploadService.createUserGroup( assmbleParams(userName,url));
        if (resultObject.getCode().equals("0000")){
            log.info("客群{}新增完毕",userName);
            return true;
        }
        return false;
    }

    private Map<String, Object> assmbleParams(String userId, String url) {
        Map<String, Object> params = Maps.newHashMap();
        params.put("userGroupName",userId);
        params.put("isFtp","0");
        params.put("fileOriname",userId+".csv");
        params.put("createWay","10");
        params.put("fileImportType","1");
        params.put("fileRename",url);
        params.put("onlySms","0");
        params.put("ftpDir",FILE_UPLOAD_PATH);
        //所有方舟客群部门统一为运营中心
        params.put("creatorName","方舟同步");
        params.put("creatorDepartment","运营中心");
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("userGroupName",userId);
        jsonObject.put("createWay","10");
        jsonObject.put("fileImportType","1");
        jsonObject.put("fileOriname",userId+".csv");
        jsonObject.put("fileRename",url);
        jsonObject.put("onlySms","0");
        jsonObject.put("ftpDir",FILE_UPLOAD_PATH);
        jsonObject.put("isFtp","0");
        params.put("groupAttribute",jsonObject.toJSONString());
        return params;
    }

    /**
     * 生成csv文件
     * @param UserGroupInfoItem
     * @return
     */
    private void PointsToCsvFile(List<ArkUserGroupInfo> UserGroupInfoItem, String url){
        if (UserGroupInfoItem!=null && UserGroupInfoItem.size() > 0){
            File csvFile = null;
            BufferedWriter csvWriter = null;
            try {
                csvFile = new File(url);
                File parent = csvFile.getParentFile();
                if (parent != null && !parent.exists()) {
                    parent.mkdirs();
                }
                csvFile.createNewFile();
                // GB2312使正确读取分隔符","
                csvWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(csvFile), "GB2312"), 1024);
                // 写入文件内容
                for (ArkUserGroupInfo userGroupInfo : UserGroupInfoItem) {
                    csvWriter.write(userGroupInfo.getPhoneNo());
                    csvWriter.newLine();
                }
                csvWriter.flush();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    csvWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private boolean updateGroupInfo(List<ArkUserGroupInfo> userGroupInfoItem, HashMap userGroupMap) {
        String groupId = userGroupMap.get("groupId").toString();
        log.info(">>>>>>>>>>>>>开始更新客群id为{}的客群",groupId);
        //因为是set，直接将新的客群进行录入
        try {
            merge(groupId + "-phone",userGroupInfoItem);
            return true;
        }catch (Exception e){
            log.error("{}更新客群异常",groupId,e);
        }
        return false;
    }

    private void merge(String key, List<ArkUserGroupInfo> userGroupInfoItem) {
        Set oldGroupset = redisService.getSet(key);
        log.info("{}在redis中的数据量：{}", key, oldGroupset.size());
        //将更新后的号码取出
        Set newGroupSet = userGroupInfoItem.stream().
                map(ArkUserGroupInfo::getPhoneNo).collect(Collectors.toSet());
        log.info("新客群的数据量是：{}",newGroupSet.size());
        //result.addAll(oldGroupset);
        redisService.remove_key(key);
        redisService.setSet(key, newGroupSet);
        log.info("{}更新完毕，当前客群容量",key);
    }

    @Override
    public void deleteArkUserGroup() {
        List<UserGroupInfo> arkGroup = userGroupInfoMapper.selectByMoreThan7Group();
        for (UserGroupInfo userGroupInfo : arkGroup) {
            log.info(">>>>>>>>>方舟客群删除超时客群gid:{}开始",userGroupInfo.getGroupId());
            // 查询当前人群是否参与策略运营
            List<HashMap<String, Object>> strategys = crowdMapper.queryPartInStrategy(userGroupInfo.getGroupId());
            if (!strategys.isEmpty()) {
                log.info("该用户群体" + userGroupInfo.getGroupId() + "正在参与活动的运营，暂不能删除。");
               continue;
            }
            List<UserGroupInfo> combinedGroup = userGroupInfoMapper.selectByCombinedGroup(userGroupInfo.getGroupId());
            if (!combinedGroup.isEmpty()){
                log.info("该用户群体 "+ userGroupInfo.getGroupId() + "被重组引用，请先删除该用户群，再进行删除。");
                continue;
            }
            try {
                deleteGroup(userGroupInfo.getGroupId());
            }catch (MyException e){
                continue;
            }
            log.info(">>>>>>>>>方舟客群删除超时客群gid:{}结束",userGroupInfo.getGroupId());
        }
    }

    private void deleteGroup(String gid){
        try {
            Map params = Maps.newHashMap();
            params.put("groupId",gid);
            params.put("createStatus", com.ebupt.migu.music.common.constants.UserGroupConstants.DELETED);
            crowdMapper.updateCrowd(params);
        } catch (Exception e) {
            log.error("删除人群失败：" + gid, e);
            throw new MyException(StatusEnum.DELETE_USER_GROUP_ERROR, "删除人群失败！");
        }
    }
}
